import hashlib
import time
from logging.handlers import RotatingFileHandler

from flask import json, request, session, jsonify, render_template
from flask_cors import CORS
import redis
import json;
import os;
import logging

from werkzeug import run_simple
from werkzeug.middleware.dispatcher import DispatcherMiddleware

from controllers.MemberController import memberController
from services.MemberService import MemberService
from db import mysql
from db.mysql.MySql import MySql
from framework.EException import EException

from flask import Flask

from controllers.SystemApi import systemApi

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)  # 生成24位的随机数种子，用于产生SESSION ID
app.config['JSON_AS_ASCII'] = False

app.jinja_env.auto_reload = True
app.config['TEMPLATES_AUTO_RELOAD'] = True

env_dist = os.environ  # environ是在os.py中定义的一个dict environ = {}
signKey = "2650a17f769d40f0a899f4385977c5a2";
resisAdd = env_dist.get('resisAdd');
if (resisAdd == None):
    resisAdd = "127.0.0.1"

redisPwd = env_dist.get('redisPwd');
if (redisPwd == None):
    redisPwd = ""

db_user = env_dist.get('db_user');
if (db_user == None):
    db_user = "sa"
db_pwd = env_dist.get('db_pwd');
if (db_pwd == None):
    db_pwd = "Yingjia85362155"
db_name = env_dist.get('db_name');
if (db_name == None):
    db_name = "snail_db"
db_add = env_dist.get('db_add');
if (db_add == None):
    db_add = "db860991001.rwlb.rds.aliyuncs.com"


mySql = MySql(db_add, db_user, db_pwd, db_name)
rd = redis.Redis(host=resisAdd, port=6379, password=redisPwd, db=0, decode_responses=True)
memberController.config["db"]=mysql;
memberController.config["redis"]=rd;

systemApi.config["db"]=mySql;
systemApi.config["redis"]=rd;


logging.basicConfig(level=logging.DEBUG)


# 日志
def setup_log():
    """配置日志"""
    # datetime.datetime.strptime(string,'%Y-%m-%d %H:%M:%S')
    # 设置日志的记录等级
    logging.basicConfig(level=logging.DEBUG)  # 调试debug级
    # 创建日志记录器，指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
    file_log_handler = RotatingFileHandler("logs/log.log", maxBytes=1024 * 1024 * 100, backupCount=10)
    # 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
    formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
    # 为刚创建的日志记录器设置日志记录格式
    file_log_handler.setFormatter(formatter)
    # 为全局的日志工具对象（flask app使用的）添加日志记录器
    logging.getLogger().addHandler(file_log_handler)


# 全局可跨域请求
CORS(app, supports_credentials=True)
CORS(app, resources=r'/*')


@app.before_request
def before():
    """
    针对app实例定义全局拦截器
    """
    url = str(request.path)  # 读取到当前接口的地址
    s = "http[{0}]:{1}".format(request.method, request.url)
    if request.method == "POST":
        s = s + "\n\t请求参数：{0}".format(request.json);
    logging.info(s);
    if url.find('/static/') == 0:
        return
    if url.find("login") >= 0:
        pass
    elif session.get('is_login', False) == False:
        # return '你还没有登录'
        return render_template('Login.html');

def sign_JsonBody(body, signKey):
    '''请求body sign签名'''
    # 列表生成式，生成key=value格式
    # a = ["".join(i) for i in body.items() if i[1] and i[0] != "sign"]
    d1 = json.dumps(body, sort_keys=True, indent=4, separators=(',', ':'));
    # print(d1)
    body = json.loads(d1);
    a = "";
    for key in body:
        a = a + key + "=" + str(body[key]) + "&";
    # a=a[:-1];
    # print(a)
    # 参数名ASCII码从小到大排序
    # strA = a+"sign=""".join(sorted(a))
    # 在strA后面拼接上apiKey得到striSignTemp字符串
    striSignTemp = a + "sign=" + signKey

    # MD5加密
    def jiamimd5(src):
        m = hashlib.md5()
        m.update(src.encode('UTF-8'))
        return m.hexdigest()

    sign = jiamimd5(striSignTemp.lower())
    # 得到sign签名后新的body值
    body["sign"] = sign
    return body


@app.after_request
def after(response):
    if response.status_code == 200:
        if (response.is_json):
            js = response.json;
            if ("code" in js):
                js["timestamp"] = int(time.time());
                js["success"] = False;
                result = js;
            else:
                result = {
                    "success": True,
                    "message": "",
                    "code": response.status_code,
                    "result": js,
                    "timestamp": int(time.time())
                };
            result = sign_JsonBody(result, signKey);
            response = jsonify(result);
    logging.info("\t返回信息：" + str(response.json));
    return response;


def checkJsonKey(json, *keys):
    if (len(keys) == 0):
        raise EException(501, "参数错误");
    for key in keys:
        if (key not in json):
            raise EException(501, "请求参数不完整【%s】" % key);

#后台登录
@app.route('/login',methods=['post'])
def post_login():
    try:
        postData = request.json;
        checkJsonKey(postData, "userName", "pwd");
        #sql="select * from sys_user where username='{0}' AND PASSWORD=MD5('{1}')".format(postData["userName"],postData["pwd"]);
        sql = "select * from sys_user where username='{0}'".format(postData["userName"]);
        userInfo=mySql.selectOne(sql)
        if (userInfo!=None):
            session['is_login']=True
            session['userInfo']=userInfo;
            session.get('is_login', '')
            return userInfo;
        else:
            return {
                "code": 501,
                "message": '用户不存在或密码错误！'
            }
    except EException as e:
        return {
            "code": e.args[0],
            "message": e.args[1]
        }
    except Exception as e:
        return {
            "code": 500,
            "message": repr(e)
        }

@app.route('/', methods=['get'])
def post_index():
    #pid = request.args.get("pid")
    sql = "SELECT * FROM sys_permission WHERE  hidden=0 " + \
          "ORDER BY sort_no"
    list = mySql.select(sql)

    # data = [
    #     {"href": "back.html", "caption": "back"},
    #     {"href": "forward.html", "caption": "forward"},
    #     {"href": "forward.html", "caption": "forwar33d"},
    # ]
    return render_template('index.html', munes=list);

@app.route('/api/getMeneItem', methods=['get'])
def get_getMeneItem():
    pid=request.args.get("pid")
    sql="SELECT * FROM sys_permission WHERE parent_id='"+pid+"' AND hidden=0 "+\
        "ORDER BY sort_no"
    list=mySql.select(sql)
    menus = [];
    for item in list:
        menuItem={
            "id":item["id"],
            "html":'<a href="#" tag=2><i class="icon icon-leaf"></i>'+item["name"]+'</a>',
            "open":False,
            "children":[{"title": ''}]
        }
        menus.append(menuItem);
    return json.dumps(menus);

@app.route('/member/list',methods=['get'])
def get_member_list():
    '''会员列表'''
    memberService=MemberService(mySql);
    pageIndex=int(request.args.get("pageIndex"))
    pageSize=int(request.args.get("pageSize"))
    if (pageIndex==None):
        pageIndex=1
    if (pageSize==None):
        pageSize=20
    list= memberService.memberList("",pageIndex,pageSize);
    return render_template('member/list.html',data=list);

@app.route('/member/pageView',methods=['get'])
def get_member_pageView():
    '''会员列表'''
    memberService = MemberService(mySql);
    list = memberService.memberList("", 1, 20);
    return render_template('member/pageView.html',data=list);

#修改会员信息页页
@app.route('/member/edit',methods=['get'])
def get_member_edit():
    memberService = MemberService(mySql);
    member=memberService.getById(request.args.get("id"));
    return render_template('member/edit.html', data=member);

dm = DispatcherMiddleware(app, {
    '/api/member': memberController,
    '/api/system': systemApi
})

if (__name__ == '__main__' or __name__ == 'app'):
    # app.run()
    # app.run(host="0.0.0.0", debug=True, port=5000);
    run_simple('0.0.0.0', port=8010, application=dm,use_debugger=True )
